package com.all.diy
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.graphics.ImageFormat
import android.graphics.Outline
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.View
import android.view.ViewOutlineProvider
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.camera.core.AspectRatio
import androidx.camera.core.CameraSelector
import androidx.camera.core.ImageCapture
import androidx.camera.core.ImageCaptureException
import androidx.camera.core.Preview
import androidx.camera.core.resolutionselector.AspectRatioStrategy
import androidx.camera.core.resolutionselector.ResolutionSelector
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.camera.view.PreviewView
import androidx.core.content.ContextCompat
import com.all.diy.utils.StorageUtils
import com.google.common.util.concurrent.ListenableFuture
import java.io.File

class UVCCameraActivity : AppCompatActivity() {
    private lateinit var text: TextView;
    private lateinit var surfaceView: PreviewView
    private var remainingTime = 9
    private var handler = Handler(Looper.getMainLooper())
    private lateinit var cameraProviderFuture: ListenableFuture<ProcessCameraProvider>
    private lateinit var imageCapture: ImageCapture
    private lateinit var cameraProvider: ProcessCameraProvider

    private var runnable = object : Runnable {
        @SuppressLint("SetTextI18n")
        override fun run() {
            if (remainingTime > 0) {
                text.text = remainingTime.toString() + ""
                remainingTime--
                handler.postDelayed(this, 1000)
            } else {
                takePhoto()
            }
        }
    }

    @SuppressLint("MissingInflatedId")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_uvc_camera)
        surfaceView = findViewById(R.id.previewView)
        text = findViewById(R.id.text)
        initializeCamera()
        applyRoundedCorners(20f)
        handler.post(runnable)
    }

    private fun applyRoundedCorners(cornerRadiusDp: Float) {
        val cornerRadiusPx = dpToPx(this, cornerRadiusDp)
        surfaceView.outlineProvider = object : ViewOutlineProvider() {
            override fun getOutline(view: View, outline: Outline) {
                outline.setRoundRect(0, 0, view.width, view.height, cornerRadiusPx)
            }
        }
        surfaceView.clipToOutline = true
        surfaceView.setScaleType(PreviewView.ScaleType.FIT_CENTER);
    }

    private fun dpToPx(context: Context, dp: Float): Float {
        return dp * context.resources.displayMetrics.density
    }

    override fun onDestroy() {
        super.onDestroy()
        try {
            handler.removeCallbacks(runnable)
            cameraProvider.unbindAll()
        }catch (e: Exception){

        }
    }

    private fun initializeCamera() {
        cameraProviderFuture = ProcessCameraProvider.getInstance(this)
        cameraProviderFuture.addListener({
            try {
                cameraProvider = cameraProviderFuture.get()
                bindCameraUseCases()
            } catch (e: Exception) {
                Toast.makeText(this, e.toString(), Toast.LENGTH_SHORT).show()
            }
        }, ContextCompat.getMainExecutor(this))
    }


    @SuppressLint("RestrictedApi")
    private fun bindCameraUseCases() {
        // 配置预览
        val preview = Preview.Builder()
            .setTargetRotation(surfaceView.display.rotation)
            .build()
            .also {
                it.setSurfaceProvider(surfaceView.surfaceProvider)
            }

        val resolutionSelector = ResolutionSelector.Builder()
            .setAspectRatioStrategy(
                AspectRatioStrategy(
                    AspectRatio.RATIO_4_3,
                    AspectRatioStrategy.FALLBACK_RULE_AUTO
                )
            ).build()

        //配置图像捕获
        imageCapture = ImageCapture.Builder()
            .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
            .setBufferFormat(ImageFormat.JPEG) // 建议配合JPEG格式
            .setJpegQuality(85) // 适当降低质量进一步提速
            .setResolutionSelector(resolutionSelector)
            .build()


        //配置相机选择器后置摄像头
        val cameraSelector = CameraSelector.Builder()
            .requireLensFacing(CameraSelector.LENS_FACING_BACK)
            .build()


        try {
            //先解绑所有用例
            cameraProvider.unbindAll()
            //绑定到生命周期
            cameraProvider.bindToLifecycle(
                this,
                cameraSelector,
                preview,
                imageCapture
            )


        } catch (e: Exception) {
            //Log.e("CameraXDemo", "Use case binding failed", e)
            Toast.makeText(this, "相机启动失败", Toast.LENGTH_SHORT).show()
        }
    }

    override fun onPause() {
        super.onPause()
        // 如果需要在暂停时释放
        cameraProvider.unbindAll()
    }

    private fun takePhoto() {
        try {
            handler.removeCallbacks(runnable)
        }catch (e: Exception){

        }
        val photoFile = File(StorageUtils.getSafeExternalFilesDir(this, null),System.currentTimeMillis().toString() + ".jpg")
        //Log.i("photoFile",photoFile.path);
        val outputOptions = ImageCapture.OutputFileOptions.Builder(photoFile).build()
        val context = this;
        imageCapture.takePicture(outputOptions,
            ContextCompat.getMainExecutor(this),
            object : ImageCapture.OnImageSavedCallback {
                override fun onImageSaved(output: ImageCapture.OutputFileResults) {
                    //子Activity返回数据
                    val resultIntent = Intent()
                    resultIntent.putExtra("url", photoFile.absolutePath)
                    setResult(RESULT_OK, resultIntent)
                    finish()
                    cameraProvider.unbindAll()
                }
                override fun onError(exception: ImageCaptureException) {
                    Toast.makeText(context,exception.toString(),Toast.LENGTH_SHORT);
                    //Log.e("CameraXDemo", "Photo capture failed: " + exception.message)
                }
            })
       }

}
